﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using DataObject.DataAccess;
using DataObject.Database;

public partial class Pages_Reservation_Calendar : Page
{
    #region Fields

    // Variables
    private IList<string> _boats;
    private DateTime _departureDate;
    private int _indexPage;
    private bool _isShowAll;
    private IList<KeyValuePair<DateTime, string>> _listDate;

    #endregion

    #region Events

    /// <summary>
    ///     Page Load
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            LoadBoat();
            GetPropertyFromQueryString();

            var dayOfWeek = (int)_departureDate.DayOfWeek;

            DateTime fromDate = _departureDate.AddDays(7 * _indexPage - dayOfWeek + 1);
            if (fromDate > _departureDate)
                fromDate = fromDate.AddDays(-7);
            DateTime toDate = fromDate.AddDays(7);

            IList<CabinStatus> list = CabinStatusDAO.CreateInstant().FindCabinStatus(_boats, fromDate, toDate, _isShowAll);
            IList<StickyEntity> stickies = StickyDAO.CreateInstant().GetStickies(fromDate, toDate);

            _listDate = new List<KeyValuePair<DateTime, string>>();

            for (DateTime i = fromDate; i < toDate; i = i.AddDays(1))
            {
                StickyEntity sticky = stickies.SingleOrDefault(s => s.StickyDate.Equals(i));
                _listDate.Add(sticky == null
                    ? new KeyValuePair<DateTime, string>(i, null)
                    : new KeyValuePair<DateTime, string>(i, sticky.Description));
            }
            IOrderedEnumerable<Appointment> query = list.GroupBy(
                c => new { c.BoatID, c.BoatColor, c.CabinID, c.CabinNumber }).Select(g =>
                    new Appointment
                    {
                        BoatID = g.Key.BoatID,
                        BoatColor = g.Key.BoatColor,
                        CabinID = g.Key.CabinID,
                        CabinNumber = g.Key.CabinNumber,
                        Monday =
                            g.Where(c => c.DepartureDate == _listDate[0].Key && c.Status > 0)
                                .Select(c => c.Booking)
                                .SingleOrDefault(),
                        Tuesday =
                            g.Where(c => c.DepartureDate == _listDate[1].Key && c.Status > 0)
                                .Select(c => c.Booking)
                                .SingleOrDefault(),
                        Wednesday =
                            g.Where(c => c.DepartureDate == _listDate[2].Key && c.Status > 0)
                                .Select(c => c.Booking)
                                .SingleOrDefault(),
                        Thursday =
                            g.Where(c => c.DepartureDate == _listDate[3].Key && c.Status > 0)
                                .Select(c => c.Booking)
                                .SingleOrDefault(),
                        Friday =
                            g.Where(c => c.DepartureDate == _listDate[4].Key && c.Status > 0)
                                .Select(c => c.Booking)
                                .SingleOrDefault(),
                        Saturday =
                            g.Where(c => c.DepartureDate == _listDate[5].Key && c.Status > 0)
                                .Select(c => c.Booking)
                                .SingleOrDefault(),
                        Sunday =
                            g.Where(c => c.DepartureDate == _listDate[6].Key && c.Status > 0)
                                .Select(c => c.Booking)
                                .SingleOrDefault()
                    }).OrderBy(r => r.BoatID).ThenBy(r => r.CabinID);

            grv.RowDataBound += grv_RowDataBound;
            grv.DataBound += grv_DataBound;
            grv.DataSource = query;
            grv.DataBind();

            //txtDepartureDate.Text = DepartureDate.ToShortDateString();
        }
    }

    /// <summary>
    ///     OnLeft Click Event
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void OnLeft(object sender, EventArgs e)
    {
        //IndexPage--;
        _departureDate = String.IsNullOrEmpty(txtDepartureDate.Text) ? DateTime.Now : Convert.ToDateTime(txtDepartureDate.Text, CultureInfo.InvariantCulture).AddDays(-7);
        _isShowAll = radShowAll.Checked;

        // Session boats to serve for search method
        _boats = new List<string>();
        foreach (ListItem item in chkBoat.Items)
        {
            if (item.Selected)
                _boats.Add(item.Value);
        }
        Session["CheckedBoats"] = _boats;

        Response.Redirect(
            string.Format(@"/Pages/Reservations/Calendar.aspx?IndexPage={0}&DepartureDate={1}&IsShowAll={2}", _indexPage,
                _departureDate.ToShortDate(), _isShowAll));
    }

    /// <summary>
    ///     OnRight Click Event
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void OnRight(object sender, EventArgs e)
    {
        //IndexPage++;
        _departureDate = String.IsNullOrEmpty(txtDepartureDate.Text) ? DateTime.Now : Convert.ToDateTime(txtDepartureDate.Text, CultureInfo.InvariantCulture).AddDays(7);
        _isShowAll = radShowAll.Checked;

        //Session["CheckedBoats"] = Boats;
        _boats = new List<string>();
        foreach (ListItem item in chkBoat.Items)
        {
            if (item.Selected)
                _boats.Add(item.Value);
        }
        Session["CheckedBoats"] = _boats;

        Response.Redirect(
            string.Format(@"/Pages/Reservations/Calendar.aspx?IndexPage={0}&DepartureDate={1}&IsShowAll={2}", _indexPage,
                _departureDate.ToShortDate(), _isShowAll));
    }

    /// <summary>
    ///     Check Cabin Click Event
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void OnCheckCabin(object sender, EventArgs e)
    {
        //IndexPage = 0;
        _departureDate = String.IsNullOrEmpty(txtDepartureDate.Text) ? DateTime.Now : Convert.ToDateTime(txtDepartureDate.Text, CultureInfo.InvariantCulture);

        _isShowAll = radShowAll.Checked;
        //Session["CheckedBoats"] = Boats;

        _boats = new List<string>();
        foreach (ListItem item in chkBoat.Items)
        {
            if (item.Selected)
                _boats.Add(item.Value);
        }
        Session["CheckedBoats"] = _boats;

        Response.Redirect(
            string.Format(@"/Pages/Reservations/Calendar.aspx?IndexPage={0}&DepartureDate={1}&IsShowAll={2}", _indexPage,
                _departureDate.ToShortDate(), _isShowAll));
    }

    /// <summary>
    ///     RowDataBound
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void grv_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.Header)
        {
            if (_listDate.Count > 6)
            {
                for (int i = 0; i < _listDate.Count && i + 2 < e.Row.Cells.Count; i++)
                {
                    string url = "/Pages/Reservations/Reservation.aspx?BoardingDate=" + _listDate[i].Key.ToShortDate();
                    e.Row.Cells[i + 2].Text =
                        string.Format(
                            "<a style=\"color: white; text-decoration: none; cursor: pointer;\" href=\"" + url +
                            "\">{0:ddd}, {0:d}</a>", _listDate[i].Key);
                    if (_listDate[i].Value != null)
                    {
                        string note;
                        if (HttpContext.Current.User.IsInRole(define.AdminRole))
                            note = string.Format(
                                @"<p style=""color: yellow; font-weight: normal; font-size: 8pt; text-align: justify; width: 110px; word-wrap: break-word;"">
                                    <a style=""color: transparent"" href=""javascript:void(0)"" onclick=""editSticky('{0}')"">
                                        <img alt='' src='/Images/Sticky.png'/></a>
                                    <a style=""color: transparent"" href=""javascript:void(0)"" onclick=""deleteSticky('{0}')"">
                                        <img alt='' src='/Images/delete.png'/></a>{1}</p>",
                                    _listDate[i].Key.ToShortDate(), _listDate[i].Value);
                        else
                            note = string.Format(
                                @"<p style=""color: yellow; font-weight: normal; font-size: 8pt; text-align: justify; width: 110px; word-wrap: break-word;"">{0}</p>", 
                                    _listDate[i].Value);
                                e.Row.Cells[i + 2].Text += note;

                    }
                }
            }
        }
        else if (e.Row.RowType == DataControlRowType.DataRow)
        {
            GridViewRow gvRow = e.Row;
            var hdfColor = gvRow.FindControl("hdfColor") as HiddenField;
            var hdfCssMonday = gvRow.FindControl("hdfCss_Monday") as HiddenField;
            var hdfCssTuesday = gvRow.FindControl("hdfCss_Tuesday") as HiddenField;
            var hdfCssWednesday = gvRow.FindControl("hdfCss_Wednesday") as HiddenField;
            var hdfCssThursday = gvRow.FindControl("hdfCss_Thursday") as HiddenField;
            var hdfCssFriday = gvRow.FindControl("hdfCss_Friday") as HiddenField;
            var hdfCssSaturday = gvRow.FindControl("hdfCss_Saturday") as HiddenField;
            var hdfCssSunday = gvRow.FindControl("hdfCss_Sunday") as HiddenField;

            if (hdfCssMonday != null) gvRow.Cells[2].CssClass = hdfCssMonday.Value;
            if (hdfCssTuesday != null) gvRow.Cells[3].CssClass = hdfCssTuesday.Value;
            if (hdfCssWednesday != null) gvRow.Cells[4].CssClass = hdfCssWednesday.Value;
            if (hdfCssThursday != null) gvRow.Cells[5].CssClass = hdfCssThursday.Value;
            if (hdfCssFriday != null) gvRow.Cells[6].CssClass = hdfCssFriday.Value;
            if (hdfCssSaturday != null) gvRow.Cells[7].CssClass = hdfCssSaturday.Value;
            if (hdfCssSunday != null) gvRow.Cells[8].CssClass = hdfCssSunday.Value;
            if (hdfColor != null && !String.IsNullOrEmpty(hdfColor.Value))
                gvRow.BackColor = Color.FromName("#" + hdfColor.Value);
        }
    }

    /// <summary>
    ///     DataBound
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void grv_DataBound(object sender, EventArgs e)
    {
        //Random rand = new Random();
        //int v = rand.Next(100, 256);
        //Color color = Color.FromArgb(v, v, v);

        for (int rowIndex = grv.Rows.Count - 2; rowIndex >= 0; rowIndex--)
        {
            GridViewRow gvRow = grv.Rows[rowIndex];
            GridViewRow gvPreviousRow = grv.Rows[rowIndex + 1];
            const int cellCount = 0;
            //for (int cellCount = 0; cellCount < gvRow.Cells.Count;
            //                                              cellCount++)
            //{
            string source = gvRow.Cells[cellCount].Text;
            string target = gvPreviousRow.Cells[cellCount].Text;

            if (source == target)
            {
                if (gvPreviousRow.Cells[cellCount].RowSpan < 2)
                {
                    gvRow.Cells[cellCount].RowSpan = 2;
                }
                else
                {
                    gvRow.Cells[cellCount].RowSpan =
                        gvPreviousRow.Cells[cellCount].RowSpan + 1;
                }
                gvPreviousRow.Cells[cellCount].Visible = false;
            }
        }
    }

    #endregion

    #region Methods

    /// <summary>
    ///     Load Boat Method
    /// </summary>
    private void LoadBoat()
    {
        List<BoatEntity> ls = BoatDAO.CreateInstant().FindBoat("", "", null, null, true, new HashSet<string>());
        chkBoat.DataSource = ls;
        chkBoat.DataTextField = "BoatName";
        chkBoat.DataValueField = "BoatID";
        chkBoat.DataBind();
    }

    /// <summary>
    ///     Get Property
    /// </summary>
    private void GetPropertyFromQueryString()
    {
        _indexPage = Request["IndexPage"] != null ? Int32.Parse(Request["IndexPage"]) : 0;

        _departureDate = Request["DepartureDate"] != null ? Convert.ToDateTime(Request["DepartureDate"], CultureInfo.InvariantCulture) : DateTime.Today;
        txtDepartureDate.Text = _departureDate.ToShortDate();

        _isShowAll = Request["IsShowAll"] == null || bool.Parse(Request["IsShowAll"]);

        if (_isShowAll)
            radShowAll.Checked = true;
        else
            radOnlyBooked.Checked = true;


        if (Session["CheckedBoats"] != null)
        {
            _boats = Session["CheckedBoats"] as IList<string>;
            foreach (ListItem item in chkBoat.Items)
            {
                if (_boats != null && _boats.Contains(item.Value))
                    item.Selected = true;
            }
        }
        else
        {
            _boats = new List<string>();
            foreach (ListItem item in chkBoat.Items)
            {
                _boats.Add(item.Value);
            }
        }
    }

    #endregion
}